﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Gnosis.Alexandria.Model.Commands
{
    public abstract class CommandBuilderBase
        : ICommandBuilder
    {
        protected CommandBuilderBase(IIdentifiable record)
        {
            _record = record;
        }

        private readonly IIdentifiable _record;
        private readonly IDictionary<string, object> _parameters = new Dictionary<string, object>();
        private readonly StringBuilder _text = new StringBuilder();

        protected IIdentifiable Record
        {
            get { return _record; }
        }

        protected static string GetParameterName(string fieldName)
        {
            return string.Format("@{0}", fieldName);
        }

        protected void AddParameter(string name, object value)
        {
            _parameters.Add(name, value);
        }

        protected void Append(string value)
        {
            _text.Append(value);
        }

        protected void AppendFormat(string format, params object[] args)
        {
            _text.AppendFormat(format, args);
        }

        protected void AppendWhereClause(long id)
        {
            Append(" WHERE Id = @Id;");
            AddParameter("Id", id);
        }

        #region ICommandBuilder Members

        public IDbCommand ToCommand(IDbConnection connection)
        {
            return ToCommand(connection, null);
        }

        public IDbCommand ToCommand(IDbConnection connection, IDbTransaction transaction)
        {
            var command = connection.CreateCommand();
            command.CommandType = CommandType.Text;
            command.CommandText = _text.ToString();

            if (transaction != null)
                command.Transaction = transaction;

            foreach (KeyValuePair<string, object> pair in _parameters)
            {
                var parameter = command.CreateParameter();
                parameter.ParameterName = GetParameterName(pair.Key);
                parameter.Value = pair.Value;
                command.Parameters.Add(parameter);
            }

            return command;
        }

        #endregion
    }
}
